package me.weijing.common.http;

import java.security.GeneralSecurityException;
import java.security.cert.X509Certificate;
import java.util.Map;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;

import me.weijing.common.ApplicationHelper;
import android.os.Build;

@SuppressWarnings("deprecation")
public abstract class HttpRequest implements Runnable {
    protected final static int TIMEOUT_CONNECT = 15000;// 连接超时
    protected final static int TIMEOUT_READ = 10000;// 读取超时

    protected String mOrigUrl;
    protected String url;
    protected HttpCallback callback;
    protected String deviceId = ApplicationHelper.getDeviceId();
    protected RequestParams params;
    protected Map<String, String> mExtraHeader = null;
    protected static final int UPLOAD_FILE_SIZE = 8;
    public static int gNetLostContinueFileLimit = 65536;

    public static void setNetLostContinueFileLimit(int val) {
        gNetLostContinueFileLimit = val;
    }

    public static int getNetLostContinueFileLimit() {
        return gNetLostContinueFileLimit;
    }

    private void addGZip() {
    }

    static {
        if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
            System.setProperty("http.keepAlive", "false");

        }
        myX509TrustManager xtm = new myX509TrustManager();
        myHostnameVerifier hnv = new myHostnameVerifier();
        SSLContext sslContext = null;
        try {
            sslContext = SSLContext.getInstance("TLS"); // 或SSL
            X509TrustManager[] xtmArray = new X509TrustManager[] { xtm };
            sslContext.init(null, xtmArray, new java.security.SecureRandom());
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }
        if (sslContext != null) {
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
        }
        HttpsURLConnection.setDefaultHostnameVerifier(hnv);

    }

    public HttpRequest(String origUrl, String url, HttpCallback callback, Map<String, String> extraHeader, RequestParams params) {
        this.url = url;
        this.mOrigUrl = origUrl;
        this.callback = callback;
        mExtraHeader = extraHeader;
        this.params = params;
        addGZip();
    }

    public HttpRequest(String origUrl, String url, Map<String, String> extraHeader) {
        this.mOrigUrl = origUrl;
        this.url = url;
        mExtraHeader = extraHeader;
        addGZip();
    }

    public HttpRequest(String origUrl, String url, HttpProgressCallback callback, Map<String, String> extraHeader) {
        this.mOrigUrl = origUrl;
        this.url = url;
        this.callback = callback;
        mExtraHeader = extraHeader;
        addGZip();
    }

    @Override
    public void run() {

        if (callback != null) {
            callback.startProgress();
        }
        try {
            execute();
            return;
        } catch (Exception e) {
            e.printStackTrace();
        } catch (Throwable t) {
            t.printStackTrace();
        }
        if (callback != null) {
            callback.serverFail(-1);
        }
    }

    public abstract void execute();

    // 管理使用哪一个 X509 证书来验证远端的安全套接字。决定是根据信任的证书授权、证书撤消列表、在线状态检查或其他方式做出的。
    static class myX509TrustManager implements X509TrustManager {

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) {
        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) {
        }

        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }
    }

    // 用于主机名验证

    // 在握手期间，如果 URL 的主机名和服务器的标识主机名不匹配，则验证机制可以回调此接口的实现程序来确定是否应该允许此连接。

    // 策略可以是基于证书的或依赖于其他验证方案。

    // 当验证 URL 主机名使用的默认规则失败时使用这些回调。
    static class myHostnameVerifier implements HostnameVerifier {

        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }
}
